#ifndef __M_ANY_H__
#define __M_ANY_H__

#include <iostream>
#include <typeinfo>
#include "../logs/log.h"

namespace Muduo
{
    class Any
    {
    public:
        Any()
        :_content(nullptr)
        {}
        //注意这里new的时候类型是placeholder<T> 而不是 placeholder，因为placeholder是一个模板类，需要显示实例化
        template <class T>
        Any(const T& val)
        :_content(new placeholder<T>(val))  
        {}
        //不能直接写为 _content(other._content)这样是浅拷贝，析构的时候会出现野指针的问题；
        Any(const Any& other)
        :_content(other._content ? other._content->Clone() : nullptr)
        {}
        ~Any()
        {
            delete _content;
        }
        //返回子类对象保存的数据的指针
        template <class T>
        T* Get()
        {
            //_content不能为空指针
            if(_content == nullptr)
            {
                LOGINFO("%s", "_content 指针为空！");
                return nullptr;
            }
            //想要获取的数据类型，必须和保存的数据类型一致
            if(typeid(T) != _content->Type())
            {
                LOGINFO("%s", "保存的数据与获取的数据类型不一致！");
                return nullptr;
            }
            //注意我们这里需要返回的是一个子类中的_val，所以先将_content强转为(placeholder<T>*)再访问成员_val
            //如果写 &(_content->_val)是错误的，因为_content是holder*类型，没有_val成员；
            return &((placeholder<T>*)_content)->_val;
        }
        Any& swap(Any& other)
        {
            std::swap(_content, other._content);
            return *this;
        }
        //赋值运算符的重载
        template <class T>
        Any& operator=(const T& val)
        {
            Any(val).swap(*this);
            return *this;
        }
        Any& operator=(const Any& other)
        {
            Any(other).swap(*this);
            return *this;
        }
    private:
        class holder
        {
        public:
            virtual ~holder(){}
            //获取子类对象保存的数据类型
            virtual const std::type_info& Type()=0;
            //针对当前的对象自身，克隆出一个新的子类对象
            virtual holder* Clone()=0;
        };
        template <class T>
        class placeholder : public holder
        {
        public:
            placeholder(const T&val)
            :_val(val)
            {}
            ~placeholder()
            {}
            //获取子类对象保存的数据类型
            const std::type_info& Type() override
            {
                return typeid(T);
            }
            //针对当前的对象自身，克隆出一个新的子类对象
            holder* Clone() override
            {
                return new placeholder<T>(_val);
            }
        public:
            T _val;
        };
    private:
        holder* _content;
    };
}

#endif
